; (function ($) {

  // 构造函数
  function ZEditor(el, options) {
    var _this = this;
    this.$el = el; // 调用节点
    this.jsonData = {};
    this.dataKey = 0;
    this.isFullScreen = false;
    this.needResetSelPos = true;
    this.currentFocus; //当前焦点元素
    this.toolHeight;
    this.defaults = { // 默认配置
      selectBtn: ['paragraph', 'title', 'link', 'image', 'center', 'fullScreen', 'importantParagraph', 'clearAll'], // 默认选择开启的功能
      upLoadURL: '/Upload/UploadImages',
      setData: {},
      toolHeightScale: 0.12
    };
    this.options = options || this.defaults; // 传入配置
    this.buttons = { // 全部可用按钮
      paragraph: {
        tips: '普通段落',
        icon: 'icon-list',
        clickEvent: function () {
          _this.checkFocus('paragraph');
          _this.createParagraph();
        }
      },
      importantParagraph: {
        tips: '着重段落',
        icon: 'icon-bold',
        clickEvent: function () {
          _this.checkFocus('importantParagraph');
          _this.createImportant();
        }
      },
      title: {
        tips: '标题',
        icon: 'icon-font-size',
        clickEvent: function () {
          var html = '<div><span class="z-editor-hsize h1">H1</span><span class="z-editor-hsize h2">H2</span><span class="z-editor-hsize h3">H3</span><span class="z-editor-hsize h4">H4</span><span class="hsize-close">取消</span></div>';
          _this.openToolLayer(html);
          var hzise = '';
          $('.z-editor-hsize').click(function () {
            hsize = $(this).text();
            _this.checkFocus('title', { 'hsize': hsize });
            _this.createTitle(hzise);
            _this.closeToolLayer();
          });
          $('.hsize-close').click(function () {
            _this.closeToolLayer();
          });
        }
      },
      center: {
        tips: '居中',
        icon: 'icon-paragraph-center',
        clickEvent: function () {
          _this.createCenter();
        }
      },
      link: {
        tips: '链接',
        icon: 'icon-link',
        clickEvent: function () {
          var html = '<div><input type="text" class="link-text" placeholder="请输入链接文本 ..."><input type="text" class="link-input" placeholder="请输入链接地址 ..."><button class="link-btn">确认</button><button class="link-close">取消</button></div>';
          _this.openToolLayer(html);
          var inp = _this.currentFocus.text();
          $('.link-text').val(inp);

          $('.link-input').focus();
          $('.link-btn').click(function () {
            var url = $('.link-input').val();
            var text = $('.link-text').val();
            if(!url || !text) {
              alert('您有地方未完整填写！');
              return;
            }
            url = /http(:|s:)\/\//g.test(url)
                  ? url
                  : 'http://' + url;
            _this.checkFocus('link', { 'url': url, 'content': text});
            if (url) _this.createLink(url, text);
            _this.closeToolLayer();
          });
          $('.link-close').click(function () {
            _this.closeToolLayer();
          });
        }
      },
      image: {
        tips: '图片',
        icon: 'icon-file-picture',
        clickEvent: function () {
          var html = '<form enctype="multipart/form-data" class="editor-file-form"><button class="img-open">选择图片</button><input name="uploadimg" type="file" class="editor-file-input"><button class="img-close">取消</button></form>';
          _this.openToolLayer(html);

          if(_this.getInputContent()) {
            _this.createParagraph();
          }
          $('.editor-file-input').change(function (e) {
            _this.createImg(e);
            _this.closeToolLayer();
          });
          $('.img-close').click(function () {
            _this.closeToolLayer();
          });
        }
      },
      fullScreen: {
        tips: '全屏',
        icon: 'icon-enlarge',
        clickEvent: function () {
          if (!_this.isFullScreen) {
            _this.setFullScreen();
          } else {
            _this.cancelFullScreen();
          }
          _this.isFullScreen = !_this.isFullScreen;
        }
      },
      clearAll: {
        tips: '清空全部',
        icon: 'icon-bin',
        clickEvent: function () {
          var r = confirm('确认删除？');
          if (r) _this.clearAll();
        }
      },
    };
  }


  $.extend(ZEditor.prototype, {
    /*
    *
    *************************界面初始化******************************
    */
    // 初始化
    init: function () {
      var _this = this;
      _this.initOption();
      _this.createComponent();
      _this.renderToEditor();
      _this.activeEvent();
      _this.listenInputEvent();
      _this.responsive();
      $(window).resize(function () {
        _this.responsive();
      });
    },

    // 初始化配置
    initOption: function () {
      var _this = this;
      var btns = _this.buttons;
      for (var def in _this.defaults) { // 遍历默认配置，如果该配置被传入，则替换默认配置
        if (typeof _this.options[def] === 'undefined') {
          _this.options[def] = _this.defaults[def];
        }
      }
      for (var btn in btns) { // 选择需要开启的按钮
        var isSelect = false;
        for (var i = 0; i < _this.options.selectBtn.length; i++) {
          if (_this.options.selectBtn[i] === btn) {
            isSelect = true;
            break;
          }
        }
        if (!isSelect) { // 删除不需要的按钮
          delete btns[btn];
        }
      }
      _this.toolHeight = _this.options.toolHeightScale * _this.$el.height(); // 初始化toolHeight
    },

    // 生成组件元素
    createComponent: function () {
      var _this = this;
      var btns = _this.buttons;
      var $rootNode = _this.createEl('div', 'z-editor', _this.$el); // 创建父节点
      var $btnNode = _this.createEl('div', 'z-editor-btns', $rootNode); // 创建按钮组节点
      var $editorNode = _this.createEl('div', 'z-editor-edit', $rootNode); // 创建可编辑区域
      var $inputEditorNode = _this.createEl('div', 'z-editor-input', $editorNode); // 创建当前编辑内容

      // 各节点样式&属性
      $rootNode.css({
        'width': _this.$el.width(),
        'height': _this.$el.height()
      });
      $btnNode.css({
        'height': _this.toolHeight
      });
      $editorNode.css({
        'height': _this.$el.height() - _this.toolHeight - 5
      });
      $inputEditorNode.attr('contenteditable', true);
      _this.currentFocus = $inputEditorNode;

      // 绘制工具条
      for (var btn in btns) {
        var $btn = _this.createEl('a', 'z-editor-btn', $btnNode); // 创建每一个按钮
        var tip = '<div class="z-editor-tooltip"></div>';
        $btn.attr('data-name', btn).html(tip).css({
          'font-size': _this.toolHeight / 2.5,
          'line-height': _this.toolHeight + 'px'
        });
        $btn.find('.z-editor-tooltip').html(btns[btn]['tips']).css({
          'top': $('.z-editor-btns').height() + 5
        })
        var $icon = _this.createEl('i', btns[btn].icon, $btn); // 创建按钮icon
        $icon.css({ 'font-size': _this.toolHeight / 2.5 });
      }
      _this.btnClickEvent();
    },


    /*
    *
    *************************事件监听******************************
    */
    // 编辑区域激活事件
    activeEvent: function () {
      var _this = this;
      $('.z-editor-input').focus(function () {
        $('.z-editor').addClass('active');
      }).blur(function () {
        $('.z-editor').removeClass('active');
      });
      $('.z-editor-edit').click(function () {
        _this.setFocus($('.z-editor-input'));
      });
    },

    // tool按钮点击事件
    btnClickEvent: function () {
      var _this = this;
      var $btn = $('.z-editor-btn');
      $btn.click(function () { // 每个按钮点击后相应自身事件
        _this.buttons[$(this).attr('data-name')].clickEvent($(this));
      });
    },

    // input区域事件
    listenInputEvent: function () {
      var _this = this;
      var $inputNode = $('.z-editor-input');
      $inputNode.keydown(function (e) {
        _this.checkNeedSelectPos(e);
        if (e.keyCode === 13) { // 回车事件
          _this.createParagraph();
          _this.scrollToBottom(); // 滚动条滚动到底部
          return false;
        }
        if (e.keyCode === 8) { // 退格事件
          if (!$inputNode.text()) {
            var $prevNode = $inputNode.prev();
            _this.setFocus($prevNode.find('.z-element-content'));
            return false;
          }
        }
        if (e.keyCode === 38 && _this.getSelectionPosition() === 0) { // 键盘up事件
          var $prevNode = $inputNode.prev();
          if ($prevNode[0]) _this.setFocus($prevNode.find('.z-element-content'));
        }
      });
    },

    // element区域事件
    listenElementEvent: function ($node) {
      var _this = this;
      var elContentLen = $node.text().split('').length;
      _this.deleteElement(); // 监听删除事件
      _this.selectEditable(); // 监听点击事件(可编辑)
      $node.keydown(function (e) { // 监听键盘事件
        elContentLen = $node.text().split('').length; // 更新content长度
        _this.checkNeedSelectPos(e);
        if (e.keyCode === 13) { // 监听回车事件
          _this.elementEnterEvent(this);
          return false;
        }
        if (e.keyCode === 8) { // 监听退格事件
          _this.elementBackspaceEvent(this);
        }
        if (e.keyCode === 38 && _this.getSelectionPosition() === 0) { // 键盘up键跳转到上一个节点
          var $prevNode = $node.prev();
          if ($prevNode[0]) _this.setFocus($prevNode.find('.z-element-content'));
        }
        if (e.keyCode === 40 && _this.getSelectionPosition() === elContentLen) { // 键盘down键跳转到下一个节点
          var $nextNode = $node.next();
          if ($nextNode[0]) _this.setFocus($nextNode.find('.z-element-content'));
        }
      });
    },

    // 点击删除element元素事件
    deleteElement: function () {
      var _this = this;
      var deleteBtn = document.querySelectorAll('.z-element-close');
      for (var i = 0; i < deleteBtn.length; i++) {
        deleteBtn[i].onclick = function (e) {
          e.preventDefault();
          var index = this.parentNode.getAttribute('data-index');
          _this.deleteJsonMember(index); // 删除按钮对应数据
          $('[data-index = ' + index + ']').remove(); // 删除按钮对应元素节点
        };
      }
    },

    // 点击选择区域可编辑事件
    selectEditable: function () {
      var _this = this;
      $('.z-element').click(function (e) { // 以添加元素被点击后可编辑，并将焦点移动到该元素
        e.stopPropagation();
        var className = $(this).attr('class');
        var isImg = /image/g.test(className);
        if (isImg) return; // 图片不允许修改
        _this.createParagraph();
        $(this).find('.z-element-content').attr('contenteditable', true).focus();
        _this.currentFocus = $(this).find('.z-element-content');

        if (_this.getSelectionPosition() === 1) { // 如果鼠标点击编辑区域偏移量为1的位置，不需要重置光标位置
          _this.needResetSelPos = false;
        }
      });
      $('.z-element-content').blur(function () { // 失焦后
        var content = $(this).text();
        var index = $(this).parent().attr('data-index');
        if (!content) { // 该元素内容为空则直接删除
          $(this).parent().remove();
          _this.deleteJsonMember(index);
        }
        else {
          $(this).attr('contenteditable', false);
          _this.modifyJsonMember(index, 'content', content);
        }
      });
    },

    // element区域回车事件
    elementEnterEvent: function (el) {
      var _this = this;
      var $el = $(el);
      var elContent = $el.text();
      var elContentLen = elContent.split('').length;
      var dataKey = _this.dataKey;
      var content = '';
      var $node;
      var prevId;
      var offset;
      var $elClass = $el.find('.z-element-content').attr('class');
      if (_this.needResetSelPos) { // 将光标偏移设置到行末
        offset = _this.getSelectionPosition() === 1 ? elContentLen : _this.getSelectionPosition();
      }
      else {
        offset = _this.getSelectionPosition();
        _this.needResetSelPos = true;
      }
      var json = {
        'id': dataKey,
        'content': content,
        'type': 'paragraph'
      };
      if (offset === 0) { // 光标处在文字起始处，在上方添加空段落
        prevId = $el.prev().attr('data-index');
        $node = _this.createZEl('z-paragraph', dataKey, content);
        $el.before($node);
      }
      else if (offset === elContentLen) { // 光标处在文字末尾处，在下方添加空段落
        prevId = $el.attr('data-index');
        $node = _this.createZEl('z-paragraph', dataKey, content);
        $el.after($node);
      }
      else { // 光标在文字中间，在下方添加段落，并将将光标后半部分文字添加到新段落
        prevId = $el.attr('data-index');
        var firstHalf = elContent.slice(0, offset);
        var secondHalf = elContent.slice(offset);
        $node = _this.createZEl('z-paragraph', dataKey, secondHalf);
        var contentHtml = '<span class="' + $elClass + '">' + firstHalf + '</span>';
        var closeBtnHtml = '<span class="z-element-close"><span class="close-line close-line1"></span><span class="close-line close-line2"></span></span>';
        $el.after($node).html(contentHtml + closeBtnHtml);
        _this.modifyJsonMember(prevId, 'content', firstHalf);
      }

      var nextId = $node.next().attr('data-index'); // 修改下方节点prevId
      _this.modifyJsonMember(nextId, 'prevId', dataKey);

      json['prevId'] = parseInt(prevId); // 添加新段落数据
      _this.jsonData[dataKey] = json;

      _this.setFocus($node.find('.z-element-content'));

      _this.dataKey++;
      _this.listenElementEvent($node);
      return $node;
    },

    // element区域退格事件
    elementBackspaceEvent: function (node) {
      var _this = this;
      var $node = $(node);
      if (!$node.text()) { // 输入框为空
        var index = $node.attr('data-index');
        var $prevNode = $node.prev();
        _this.setFocus($prevNode.find('.z-element-content'));
        _this.deleteJsonMember(index); // 删除该数据
        $('[data-index = ' + index + ']').remove(); // 删除该元素节点
        return false;
      }
      else if (_this.getSelectionPosition() === 0 && _this.getSelectionEndPosition() === 0) { // 输入框不为空，但光标位于输入框最前面
        var $prevNode = $node.prev();
        if ($prevNode[0] && !(/image/g.test($prevNode.attr('class')))) {
          var index = $node.attr('data-index');
          var prevNodeIndex = $prevNode.attr('data-index');
          var prevNodeContent = $prevNode.text() + $node.text();
          _this.deleteJsonMember(index); // 删除该数据
          _this.modifyJsonMember(prevNodeIndex, 'content', prevNodeContent);
          $('[data-index = ' + prevNodeIndex + ']').find('.z-element-content').text(prevNodeContent);
          $('[data-index = ' + index + ']').remove(); // 删除该元素节点
          _this.setFocus($prevNode.find('.z-element-content'));
          return false;
        }
      }
    },

    // 添加图片描述事件
    listenAddImgDescEvent: function () {
      var _this = this;
      $('.add-img-desc').click(function () {
        var $this = $(this);
        var index = $this.parent().parent().attr('data-index');
        $this.focus(function () {
          if ($this.text() === '双击添加图片描述') {
            $this.text('');
          }
        });
        $this.attr('contenteditable', true).blur(function () {
          if ($this.text() === '双击添加图片描述') {
            _this.modifyJsonMember(index, 'describe', '');
          }
          else if ($this.text() === '') {
            $this.text('双击添加图片描述');
            _this.modifyJsonMember(index, 'describe', '');
          }
          else {
            _this.modifyJsonMember(index, 'describe', $this.text());
          }
        }).keydown(function (e) {
          if (e.keyCode === 8 && !$this.text()) return false;
          if (e.keyCode === 13) {
            _this.setFocus($('.z-editor-input'));
            return false;
          }
        });
      });
    },


    /*
    *
    *************************焦点相关******************************
    */
    // 检查焦点位置
    checkFocus: function (type, arg) { // 此时点击的按钮类型，如果类型是链接额外传入url
      var _this = this;
      if (/z-element-content/g.test(_this.currentFocus.attr('class'))) { // 如果当前焦点处在已添加的元素上
        var index = _this.currentFocus.parent().attr('data-index'); // 获取当前焦点元素id
        var content = _this.currentFocus.text();
        var className = _this.currentFocus.parent().attr('class');
        _this.modifyJsonMember(index, 'type', type); // 修改该部分数据type
        _this.modifyJsonMember(index, 'content', content); // 修改该部分数据content
        _this.currentFocus.parent().attr('class', 'z-' + type + ' z-element'); // 修改该元素class

        var isLink = /link/g.test(className);
        var isTitle = /title/g.test(className);
        if (isLink) { // 如果当前元素是链接(把链接更改为其他)，删除数据中的url项
          _this.deleteJsonMemberKey(index, 'url');
        }
        if (isTitle) {
          _this.deleteJsonMemberKey(index, 'size');
        }
        if (type === 'link') { // 如果点击的按钮是链接（把其他更改为链接），在数据中添加url项
          _this.modifyJsonMember(index, 'url', arg['url']);
          _this.currentFocus.text(arg['content']); // 链接比较特殊，可以主动修改焦点文字内容
          _this.modifyJsonMember(index, 'content', arg['content']);
        }
        if (type === 'title') { // 如果点击的按钮是标题，在数据中添加标题size项
          _this.modifyJsonMember(index, 'size', arg['hsize']);
          _this.currentFocus.parent().addClass(arg['hsize']);
        }
        _this.setFocus(_this.currentFocus);
      }
    },

    // 设置当前焦点
    setFocus: function ($node) {
      var _this = this;
      if (!/image/g.test($node.parent().attr('class'))) { // 图片不允许获得焦点
        $node.attr('contenteditable', true).focus();
        _this.currentFocus = $node;
        if (!(/z-editor-input/g.test($node.attr('class')))) {
          _this.cursorToEnd($node[0]); // 光标移动到行尾
        }
      }
    },


    /*
    *
    *************************工具弹出层相关******************************
    */
    // 关闭工具框
    closeToolLayer: function () {
      $('.z-editor-layer').remove();
    },

    // 打开工具框
    openToolLayer: function (html) {
      var layer = $('.z-editor-layer')[0];
      if (typeof layer === 'undefined') {
        var $layerNode = this.createEl('div', 'z-editor-layer', $('.z-editor'));
        $layerNode.html(html);
      }
    },


    /*
    *
    *************************创建新element元素******************************
    */
    // 添加居中
    createCenter: function () {
      var _this = this;
      if (/z-element-content/g.test(_this.currentFocus.attr('class'))) { // 如果当前焦点处在已添加的元素上
        var index = _this.currentFocus.parent().attr('data-index'); // 获取当前焦点元素id
        var content = _this.currentFocus.text();
        var className = _this.currentFocus.parent().attr('class');
        var currentFocusJSON = _this.queryJsonMember(index);
        if (currentFocusJSON['align'] === 'center') {
          _this.deleteJsonMemberKey(index, 'align');
          _this.currentFocus.removeClass('z-element-center');
        }
        else {
          _this.modifyJsonMember(index, 'align', 'center');
          _this.currentFocus.addClass('z-element-center');
        }
        _this.setFocus(_this.currentFocus);
      }
    },

    // 创建着重段落
    createImportant: function () {
      var _this = this;
      var content = _this.getInputContent();
      var dataKey = _this.dataKey; // 该项数据key值
      if (content) { // 添加段落到input上方
        _this.setFocus($('.z-editor-input')); // 焦点还原到input
        _this.addElementBeforeInput('z-importantParagraph', dataKey, content);
      }
      var prevId = $('[data-index = ' + dataKey + ']').prev() ? parseInt($('[data-index = ' + dataKey + ']').prev().attr('data-index')) : -1; // 该项数据的上一项id
      if (content) {
        var paragraphJSON = {
          'prevId': prevId,
          'id': dataKey,
          'content': content,
          'type': 'importantParagraph'
        };
        _this.jsonData[dataKey] = paragraphJSON; //添加数据
        _this.dataKey++;
        _this.scrollToBottom();
      }
    },

    // 创建图片
    createImg: function (e) {
      var _this = this;
      var dataKey = _this.dataKey;
      var imgJSON = {};
      this.setFocus($('.z-editor-input'));

      var loadingTips = '请稍等，图片上传中.... <i class="icon-spinner2"></i>'; // 等待上传提示
      _this.addElementBeforeInput('z-image', dataKey, loadingTips);
      var $imgNode = $('[data-index = ' + dataKey + ']');
      $imgNode.find('.z-element-close').hide();

      $('.editor-file-form').ajaxSubmit({ // 提交表单文件
        url: _this.options.upLoadURL,
        type: "post",
        success: function (path) {
          $imgNode.mouseover(function () {
            $imgNode.find('.z-element-close').show();
          });
          var path1 = 'http://static.lessonplan.cn/'+path;
          var content = '<img src="' + path1 + '" alt=""><span class="add-img-desc">双击添加图片描述</span>';
          $imgNode.find('.z-element-content').html(content);
          var $img = $imgNode.find('img');

          if ($img.width() >= $imgNode.width()) {
            $img.css('width', '100%');
          }
          var prevId = $imgNode.prev() ? parseInt($imgNode.prev().attr('data-index')) : -1;
          imgJSON['prevId'] = prevId;
          imgJSON['id'] = dataKey;
          imgJSON['type'] = 'image';
          imgJSON['path'] = path; // 返回图片路径
          imgJSON['describe'] = '';

          _this.listenAddImgDescEvent(); // 监听添加图片描述事件

          _this.jsonData[dataKey] = imgJSON;
          _this.dataKey++;
        },
        error: function () {
          alert('抱歉，上传图片失败，请重试！');
          $imgNode.remove();
        }
      })
    },

    // 创建链接
    createLink: function (url, content) {
      var _this = this;
      var dataKey = _this.dataKey;

      if ( _this.currentFocus.attr('class') === 'z-editor-input' ) {
        _this.setFocus($('.z-editor-input'));
        _this.addElementBeforeInput('z-link', dataKey, content);
      }
      var prevId = $('[data-index = ' + dataKey + ']').prev() ? parseInt($('[data-index = ' + dataKey + ']').prev().attr('data-index')) : -1;
      if ( _this.currentFocus.attr('class') === 'z-editor-input' ) {
        var linkJSON = {
          'prevId': prevId,
          'id': dataKey,
          'content': content,
          'type': 'link',
          'url': url
        };
        _this.jsonData[dataKey] = linkJSON;
        _this.dataKey++;
        _this.scrollToBottom();
      }
    },

    // 创建标题
    createTitle: function (hzise) {
      var _this = this;
      var content = _this.getInputContent();
      var dataKey = _this.dataKey;
      if (content) {
        _this.setFocus($('.z-editor-input'));
        var className = 'z-title ' + hsize;
        _this.addElementBeforeInput(className, dataKey, content);
      }
      var prevId = $('[data-index = ' + dataKey + ']').prev() ? parseInt($('[data-index = ' + dataKey + ']').prev().attr('data-index')) : -1;
      if (content) {
        var titleJSON = {
          'prevId': prevId,
          'id': dataKey,
          'content': content,
          'type': 'title',
          'size': hsize
        };
        _this.jsonData[dataKey] = titleJSON;
        _this.dataKey++;
        _this.scrollToBottom();
      }
    },

    // 创建段落
    createParagraph: function () {
      var _this = this;
      var content = _this.getInputContent();
      var dataKey = _this.dataKey; // 该项数据key值
      if (content) { // 添加段落到input上方
        _this.setFocus($('.z-editor-input')); // 焦点还原到input
        _this.addElementBeforeInput('z-paragraph', dataKey, content);
      }
      var prevId = $('[data-index = ' + dataKey + ']').prev() ? parseInt($('[data-index = ' + dataKey + ']').prev().attr('data-index')) : -1; // 该项数据的上一项id
      if (content) {
        var paragraphJSON = {
          'prevId': prevId,
          'id': dataKey,
          'content': content,
          'type': 'paragraph'
        };
        _this.jsonData[dataKey] = paragraphJSON; //添加数据
        _this.dataKey++;
        _this.scrollToBottom();
      }
    },


    /*
    *
    *************************焦点光标相关******************************
    */
    // 获取range对象
    getRangeObj: function () {
      var rangeObj;
      if (window.getSelection) {
        var sel = window.getSelection();
        if (sel.rangeCount > 0) {
          rangeObj = sel.getRangeAt(0); // 获取range对象
        }
      }
      else if (document.selection) { // IE兼容
        rangeObj = document.selection.createRange();
      }
      return rangeObj;
    },

    // 获取光标选择区域末尾
    getSelectionEndPosition: function () {
      return this.getRangeObj().endOffset;
    },

    // 获取光标偏移量
    getSelectionPosition: function () {
      return this.getRangeObj().startOffset;
    },

    // 将光标移动到末尾
    cursorToEnd: function (el) {
      var _this = this;
      if (el) {
        if (window.getSelection) {
          var sel = window.getSelection();
          sel.selectAllChildren(el);
          sel.collapseToEnd();
        } else if (document.selection) {
          var rangeObj = document.selection.createTextRange();
          rangeObj.moveToelentText(el);
          rangeObj.collapse(false);
          rangeObj.select();
        }
      }
      else {
        _this.setFocus($('.z-editor-input'));
      }
    },

    // 检测是否需要重置光标
    checkNeedSelectPos: function (e) {
      var _this = this;
      if (e.keyCode === 33 || e.keyCode === 38 || e.keyCode === 37 || e.keyCode === 36) { // 如果回车前使用键盘将光标左移，不需要重置光标位置(up,left,Home,PgUp)
        _this.needResetSelPos = false;
      }
      if (e.keyCode === 8) {
        _this.needResetSelPos = true;
      }
    },


    /*
    *
    *************************JSON数据操作******************************
    */
    // 查询指定索引数据项
    queryJsonMember: function (index) {
      var _this = this;
      for (var key in _this.jsonData) {
        if (key === index) {
          return _this.jsonData[key];
        }
      }
    },

    // 删除指定索引数据项
    deleteJsonMemberKey: function (index, deepkey) {
      var _this = this;
      for (var key in _this.jsonData) {
        if (key === index) {
          delete _this.jsonData[key][deepkey];
          break;
        }
      }
    },

    // 修改,增加指定索引数据项
    modifyJsonMember: function (index, deepkey, value) {
      var _this = this;
      for (var key in _this.jsonData) {
        if (key === index) {
          _this.jsonData[key][deepkey] = value;
          break;
        }
      }
    },

    // 删除指定索引数据
    deleteJsonMember: function (index) {
      var _this = this;
      var prevId; // 当前点击删除数据prevId
      var id; // 当前点击删除数据id
      for (var key in _this.jsonData) {
        if (key === index) { // 删除对应索引的数据
          prevId = _this.jsonData[key]['prevId'];
          id = _this.jsonData[key]['id'];
          delete _this.jsonData[key];
          break;
        }
      }
      for (var key in _this.jsonData) {
        if (_this.jsonData[key]['prevId'] === id) { // 找到prevId等于当前所删除数据的数据
          _this.jsonData[key]['prevId'] = prevId; // 将该数据的prevId改为所删除数据prevId
        }
      }
    },


    /*
    *
    *************************工具函数******************************
    */
    // 获取Input区域内容
    getInputContent: function () {
      var content = $('.z-editor-input').text();
      return content;
    },

    // 清除全部
    clearAll: function () {
      var _this = this;
      _this.jsonData = {};
      $('.z-element').remove();
      $('.z-editor-input').text('');
      _this.setFocus($('.z-editor-input'));
    },

    // 获取JSON对象
    getJSON: function () {
      var _this = this;
      if (_this.currentFocus.attr('class') === 'z-editor-input') {
        _this.createParagraph();
      }
      var jsonString = JSON.stringify(_this.jsonData).replace(/\\n/g, '');
      return JSON.parse(jsonString);
    },

    // 获取JSON对象字符串
    getJsonString: function () {
      var _this = this;
      if (_this.currentFocus.attr('class') === 'z-editor-input') {
        _this.createParagraph();
      }
      var jsonString = JSON.stringify(_this.jsonData).replace(/\\n/g, '');
      let json = JSON.parse(jsonString);
      return JSON.stringify(json).replace(/\\"/g, '\\\\"');
    },

    // 滚动条滚动到底部
    scrollToBottom: function () {
      $('.z-editor-edit').scrollTop($('.z-editor-edit')[0].scrollHeight);
    },

    // 创建元素节点
    createEl: function (el, className, parentNode) {
      var $node = $(document.createElement(el));
      $node.addClass(className);
      parentNode.append($node);
      return $node;
    },

    // 输入框前创建节点
    addElementBeforeInput: function (className, index, content) {
      var _this = this;
      var $node = _this.createZEl(className, index, content);
      $('.z-editor-input').before($node).html('');
      _this.listenElementEvent($node);
      return $node;
    },

    // 创建z-element节点
    createZEl: function (className, index, content) {
      var $node = $(document.createElement('div'));
      $node.addClass(className + ' z-element').attr('data-index', index);
      var contentHtml = '<span class="z-element-content">' + content + '</span>'; // 内容区域
      var closeBtnHtml = '<span class="z-element-close"><span class="close-line close-line1"></span><span class="close-line close-line2"></span></span>'; // 删除按钮
      $node.html(contentHtml + closeBtnHtml);
      return $node;
    },

    // 将JSON数据渲染到editor
    renderToEditor: function () {
      var _this = this;
      var json = _this.options.setData;
      if ($.isEmptyObject(json)) return;
      var prevId;
      var maxId = 0; // 传入的json数据中最大的ID值
      var isEnd = true;
      _this.jsonData = json; // 将传入的json同步到jsonData
      for (var key in json) {
        if (isNaN(json[key]['prevId']) || json[key]['prevId'] === null) {
          render(key);
          prevId = json[key]['id'];
        }
      }
      while (true) {
        for (var key in json) {
          if (json[key]['prevId'] === prevId) {
            render(key);
            if (json[key]['id'] > maxId) {
              maxId = json[key]['id'];
            }
            prevId = json[key]['id'];
            isEnd = false;
            break;
          }
        }
        if (isEnd) break;
        isEnd = true;
      }
      _this.dataKey += (maxId + 1);
      function render(key) {
        var type = json[key]['type'];
        var $node;
        switch (type) {
          case 'paragraph':
            $node = _this.addElementBeforeInput('z-paragraph', json[key]['id'], json[key]['content']);
            _this.checkFocus('paragraph');
            break;
          case 'title':
            var className = 'z-title ' + json[key]['size'];
            $node = _this.addElementBeforeInput(className, json[key]['id'], json[key]['content']);
            _this.checkFocus('title', { 'hsize': json[key]['size'] });
            break;
          case 'link':
            $node = _this.addElementBeforeInput('z-link', json[key]['id'], json[key]['content']);
            _this.checkFocus('link', { 'url': json[key]['url'] });
            break;
          case 'importantParagraph':
            $node = _this.addElementBeforeInput('z-importantParagraph', json[key]['id'], json[key]['content']);
            _this.checkFocus('importantParagraph');
            break;
          case 'image':
            var describe = json[key]['describe'] ? json[key]['describe'] : '双击添加图片描述';
            var content = '<img src="' +'http://static.lessonplan.cn/'+ json[key]['path'] + '" alt=""><span class="add-img-desc">' + describe + '</span>';
            $node = _this.addElementBeforeInput('z-image', json[key]['id'], content);
            var $image = $('[data-index = ' + json[key]['id'] + ']');
            if ($image.find('img').width() > $image.width()) {
              $image.find('img').css({ 'width': $image.width() })
            }
            _this.listenAddImgDescEvent();
            break;
        }
        if (json[key]['align']) {
          $node.find('.z-element-content').addClass('z-element-center');
        }
      }
    },

    // 将JSON数据渲染到html
    renderToHTML: function ($containerNode) {
      var _this = this;
      var json = _this.getJSON();
      var prevId;
      var isEnd = true;
      $containerNode.html('');
      for (var key in json) {
        if (isNaN(json[key]['prevId'])) {
          render(key);
          prevId = json[key]['id'];
        }
      }
      while (true) {
        for (var key in json) {
          if (json[key]['prevId'] === prevId) {
            render(key);
            prevId = json[key]['id'];
            isEnd = false;
            break;
          }
        }
        if (isEnd) break;
        isEnd = true;
      }
      function render(key) {
        var type = json[key]['type'];
        var $node;
        switch (type) {
          case 'paragraph':
            $node = _this.createEl('p', 'z-render-paragraph', $containerNode);
            $node.html(json[key]['content']);
            break;
          case 'title':
            $node = _this.createEl('p', 'z-render-title', $containerNode);
            $node.html(json[key]['content']).addClass(json[key]['size']);
            break;
          case 'link':
            $node = _this.createEl('a', 'z-render-link', $containerNode);
            $node.html(json[key]['content']).attr('href', json[key]['url']);
            break;
          case 'importantParagraph':
            $node = _this.createEl('p', 'z-render-importantParagraph', $containerNode);
            $node.html(json[key]['content']);
            break;
          case 'image':
            var $image = _this.createEl('div', 'z-render-image', $containerNode);
            var describe = json[key]['describe'] ? json[key]['describe'] : '';
            var img = '<img src="' + json[key]['path'] + '" alt=""><span class="z-img-desc">' + describe + '</span>';
            $image.html(img);
            if ($image.find('img').width() > $image.width()) {
              $image.find('img').css({ 'width': $image.width() })
            }
            break;
        }
        if (json[key]['align']) {
          $node.addClass('z-element-center');
        }
      }
    },


    /*
    *
    *************************全屏操作******************************
    */
    // 设置全屏
    setFullScreen: function () {
      var _this = this;
      function setFS() {
        $('.z-editor').addClass('full-screen');
        var toolHeight = $('.z-editor-btn').height();
        $('.z-editor-btn').css({
          'line-height': toolHeight + 'px',
          'padding': '0 15px'
        });
        $('.z-editor-btn i').css({ 'font-size': toolHeight / 3 });
        $('.z-editor-tooltip').css({ 'top': toolHeight + 5 });
      }
      setFS();
      $(window).resize(function () {
        if (_this.isFullScreen) {
          setFS();
        }
      });
    },

    // 退出全屏
    cancelFullScreen: function () {
      var _this = this;
      $('.z-editor').removeClass('full-screen');
      $('.z-editor-btn').css({ 'line-height': _this.toolHeight + 'px' });
      $('.z-editor-tooltip').css({ 'top': _this.toolHeight + 5 });
      _this.responsive();
    },


    /*
    *
    *************************自适应******************************
    */
    responsive: function () {
      var _this = this;
      $('.z-editor').css({
        'width': _this.$el.width(),
        'height': _this.$el.height()
      });
      if (_this.$el.width() <= 320) {
        $('.z-editor-btn').css({ 'padding': '0 8px' });
        $('.z-editor-btn i').css({ 'font-size': '14px' });
      }
      else {
        $('.z-editor-btn').css({ 'padding': '0 12px' });
        $('.z-editor-btn i').css({ 'font-size': '16px' });
      }
    },
  });


  // 构造函数封装
  $.fn.zeditor = function (options) {
    var zeditor = new ZEditor(this, options)
    zeditor.init();
    return zeditor;
  }

})(jQuery)
